home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 014 / xone21.arc / XONE21.ASM next >
Encoding:
Assembly Source File  |  1986-11-12  |  15.9 KB  |  749 lines

  1.     page    75,132
  2.     title    XONE - Make one ARC file from a member file
  3.  
  4. ; usage:
  5. ;       XONE inputname[.ARC] [filename] [outputname] [/R]
  6. ;
  7. ; remarks:
  8. ;    The 'inputname' is required. It defines the ARC archive
  9. ;    file which contains the member files that you want to extract.
  10. ;    The extension defaults to .ARC.
  11. ;
  12. ;    The 'filename' is optional. If omitted, all files in the
  13. ;    archive are extracted. If supplied, only that file in the
  14. ;    archive that matches the 'filename' is extracted.
  15. ;    Each extracted file is created in the ARC format using the
  16. ;    the original file name.
  17. ;
  18. ;    The 'outputname' is optional. If supplied, it defines the name
  19. ;    to be used for the extracted file. To use this operand, you must
  20. ;    also supply the 'filename' operand to extract a single file.
  21. ;
  22. ; restrictions:
  23. ;    XONE was written by Vernon Buerg and is for use without
  24. ;    restrictions. Please try to distribute this program as-is,
  25. ;    and without modification.
  26.  
  27.     .xlist
  28. print    macro    name            ; display a field
  29.     mov    dx,offset name
  30.     call    prints
  31.     endm
  32.  
  33. printl    macro    text,ctl        ; display a literal
  34.     local    txt,nxt
  35.     mov    dx,offset txt
  36.     call    prints
  37.     jmp    nxt
  38. txt    db    cr,lf,&text
  39.     ifnb    < ctl>
  40.     db    cr,lf,stopper
  41.     else
  42.     db    stopper
  43.     endif
  44. nxt    equ    $
  45.     endm
  46.  
  47.     .sall
  48.     .list
  49.  
  50. header    struc                ; archive header
  51. mbrcode db    0            ;  compression code
  52. mbrname db    13 dup (0)        ;  file name
  53. mbrsize dw    0,0            ;  file size in archive
  54. mbrdate dw    0            ;  creation date
  55. mbrtime dw    0            ;  creation time
  56. mbrcrc    dw    0            ;  cyclic redunancy check
  57. mbrlen    dw    0,0            ;  true file size, bytes
  58. header    ends
  59.  
  60. cseg    segment public para 'CODE'
  61.     assume    cs:cseg,ds:cseg,es:cseg
  62.     org    100h
  63.  
  64. xone    proc    far
  65.     jmp    start            ; do our thing
  66.  
  67. version db    cr,'   ',cr,lf          ; overlay jmp above
  68.     db    '  XONE   Make ARC file from member file(s) ',cr,lf
  69.     db    '  ----   Version 2.1 - by Vern Buerg',cr,lf,stopper
  70. usage    db    cr,lf,'  usage: XONE  archive[.ARC]  [filespec] [output] [/R]'
  71.     db    cr,lf,eof
  72.     page
  73. ;
  74. ;    return with error
  75.  
  76. error:    mov    ax,cs            ; insure seg regs
  77.     mov    ds,ax            ;  for proper exit
  78.     mov    sp,cs:stkptr
  79.     mov    errlvl,1        ; set bad return code
  80. ;    mov    dl,7            ; send bel char
  81. ;    mov    ah,2            ;  to standard output
  82. ;    int    21h
  83.  
  84. ;    set DOS error level and exit
  85.  
  86. exit:    mov    sp,cs:stkptr        ; just in case
  87.     mov    al,errlvl        ; return code
  88.     mov    ah,4ch            ; exit function
  89.     int    21h
  90.  
  91.     subttl    '--- constants, equates and work areas'
  92.     page
  93.  
  94. cr    equ    13
  95. lf    equ    10
  96. bel    equ    7
  97. tab    equ    9
  98. eof    equ    26
  99.  
  100. stopper equ    255        ; end of display line indicator
  101. arcmark equ    26        ; special archive marker
  102. xoneer    equ    8        ; highest compression code used
  103.  
  104. stkptr    dw    0        ; stack pointer upon entry
  105. errlvl    db    0        ; dos error level returned
  106. psp    dw    0        ; addr of psp
  107.  
  108. prompt    db    ' already exists, re-use it? (y/N) ',stopper
  109. answer    db    'n',cr,stopper
  110. found    db    0        ; indicates if found a member
  111. reuse    db    0        ; non-zero means overwrite existing file(s)
  112.  
  113. notfnd    db    cr,'  Member file not found - '
  114. member    db    13 dup (0),0    ; selected member name
  115.     db    cr,lf,stopper
  116.  
  117. archdl    dw    0        ; ARC file handle
  118. arcname db    76 dup (stopper)
  119.  
  120. outmsg    db    ' -> '          ; tells you what is being used
  121. outname db    76 dup (0)    ; output file name
  122.  
  123. ;    i/o control variables
  124.  
  125. inbufsz equ    18*1024     ; size of input buffer
  126. inadr    dw    offset inbuf    ; offset to input buffer
  127. inptr    dw    offset inbuf    ; offset to current byte
  128. insize    dw    inbufsz     ; size of input buffer
  129. inlen    dw    0        ; bytes left in buffer
  130. incurh    dw    0        ; current file offset
  131. incurl    dw    0        ;  low word
  132.  
  133. outbufsz equ    18*1024     ; size of output buffer
  134. outlen    dw    outbufsz    ; bytes empty in output buffer
  135. outadr    dw    offset outbuf    ; offset to output buffer
  136. outptr    dw    offset outbuf    ; spot for next output char
  137. outsize dw    outbufsz    ; size of output buffer
  138. outhdl    dw    0        ; output file handle
  139.  
  140. vline    db    cr,lf
  141. vstyle    db    '        '      ; compression method
  142.     db    'ed: '
  143. vname    db    12 dup (0),0
  144.     db    stopper,0
  145.  
  146. styles    db    '     sav'      ; 1 = old, no compression
  147.     db    '     Sav'      ; 2 = new, no compression
  148.     db    '    Pack'      ; 3 = dle for repeat chars
  149.     db    '  Squeez'      ; 4 = huffman encoding
  150.     db    '  crunch'      ; 5 = lz, no crc
  151.     db    '  crunch'      ; 6 = lz with crc
  152.     db    '     SEA'      ; 7 = internal SEA use
  153.     db    '  Crunch'      ; 8 = new lz with crc
  154.  
  155. wtg    dw    0        ; index into where table
  156.  
  157. where    dw    offset copy1    ; offset to routines for each type
  158.     dw    offset copy2
  159.     dw    offset unpack3
  160.     dw    offset unsqueez4
  161.     dw    offset uncrunch5
  162.     dw    offset uncrunch6
  163.     dw    offset uncrunch7
  164.     dw    offset uncrunch8
  165.  
  166.     subttl    '--- mainline processing'
  167.     page
  168. ;
  169. ;    gather command line operands
  170.  
  171. start:
  172.     mov    stkptr,sp        ; save stack ptr
  173.     mov    ax,cs
  174.     mov    ds,ax            ; set local data seg
  175.     mov    cx,es
  176.     mov    psp,cx            ; save psp addr
  177.     mov    es,ax
  178.  
  179.     print    version         ; display program version
  180.  
  181.     mov    si,80h            ; get command line operand
  182.     sub    cx,cx
  183.     or    cl,byte ptr [si]    ; any operand?
  184.     jnz    parm1
  185.  
  186. parm_error:
  187.     print    usage            ; no, gotta have the ARC name
  188.     jmp    error
  189.  
  190. ;    pick off any trailing '/R' parameter
  191.  
  192. parm1:    inc    si            ; point to operand
  193.     mov    bx,si
  194.     add    bx,cx            ; point to end of command line
  195.     cmp    word ptr -2[bx],'R/'    ; is reuse specified?
  196.     je    parm1r
  197.     cmp    word ptr -2[bx],'r/'
  198.     jne    parm2
  199. parm1r: or    reuse,1         ; indicate no checking
  200.     mov    word ptr -2[bx],0d0dh    ; stop command line here
  201.     sub    cx,2            ; remove /R from command line
  202.     jle    parm_error        ; oops, something is missing
  203.  
  204. ;    get first operand - input archive file name
  205.  
  206. parm2:    lodsb                ; strip leading blanks
  207.     cmp    al,' '
  208.     loope    parm2
  209.     mov    di,offset arcname
  210.     stosb
  211.  
  212. parm3:    lodsb                ; copy ARC filename
  213.     cmp    al,cr            ; end of name?
  214.     je    parm4
  215.     cmp    al,' '                  ; delimiter?
  216.     je    parm4
  217.     cmp    al,tab            ; delimiter?
  218.     je    parm4
  219.     cmp    al,','                  ; delimiter?
  220.     je    parm4
  221.     stosb
  222.     cmp    al,'.'                  ; got extension now?
  223.     je    parm5            ; yup, that's nice
  224.     loop    parm3
  225.  
  226. parm4:    mov    ax,'A.'                 ; append default ext
  227.     stosw
  228.     mov    ax,'CR'
  229.     stosw
  230.     jmp    short parm6
  231.  
  232. ;    strip trailing blanks looking for second operand
  233.  
  234. parm5:    lodsb                ; next ext char
  235.     cmp    al,cr            ; end of it?
  236.     je    parm6
  237.     cmp    al,' '                  ; delimiter?
  238.     je    parm6
  239.     cmp    al,tab            ; another delimiter?
  240.     je    parm6
  241.     stosb                ; copy supplied extension
  242.     loop    parm5
  243. parm5a: dec    di            ; back up to end of ext
  244.  
  245. parm6:    mov    al,0            ; append asciiz stopper
  246.     stosb
  247.  
  248. ;    copy optional second (file selection) operand
  249.  
  250.     or    cx,cx            ; another operand?
  251.     jz    parm_done        ; nope, extract all files
  252.     mov    di,offset member
  253. parm7:    lodsb
  254.     cmp    al,cr            ; end of operand?
  255.     je    parm20            ; yes, done
  256.     cmp    al,' '                  ; delimiter for third operand?
  257.     je    parm10
  258.     cmp    al,tab
  259.     je    parm10
  260.     cmp    al,'a'                  ; lower case?
  261.     jb    parm8
  262.     sub    al,32
  263. parm8:    stosb
  264.     loop    parm7
  265. parm9:    mov    ax,0ff00h        ; append asciiz stopper
  266.     stosw
  267.     jmp    short parm_done
  268.  
  269. ;    get third operand, if any, as output file name
  270.  
  271. parm10: sub    cx,1            ; account for delimiter
  272.     jle    parm_done
  273.     mov    di,offset outname    ; third operand is target filename
  274. parm11: lodsb
  275.     cmp    al,' '                  ; strip leading blanks
  276.     loope    parm11
  277.     cmp    al,cr            ; ending c/r?
  278.     je    parm_done        ;  just trailing blanks, then
  279.     jcxz    parm20
  280. parm12: stosb                ; blindly copy the rest
  281.     lodsb
  282.     cmp    al,cr
  283.     loopne    parm12
  284. parm20: mov    ax,0ff00h        ; append stoppers
  285.     stosw
  286.  
  287. parm_done:                ; hope we've got everything
  288.     call    openarc         ; access the archive file
  289.     jnc    xonenext
  290.     ret
  291.  
  292.     page
  293. ;
  294. ;    process next archive header entry
  295.  
  296. xonenext:
  297.     call    gethdr            ; load next header
  298.     jnc    xone2            ; get CF at end of file, etc
  299.     jmp    exit            ; all done
  300.  
  301. xone2:    cmp    archdr.mbrcode,0    ; archive eof?
  302.     jne    xone2a            ; nope, keep on truckin
  303.  
  304.     printl    ' '                     ; blank line
  305.  
  306.     call    closarc         ; close file
  307.     cmp    member,0        ; selecting one file?
  308.     je    xone_ok         ; no, skip next
  309.     cmp    found,0         ; and did we get it?
  310.     jne    xone_ok
  311.     print    notfnd
  312.     printl    ' '
  313. xone_ok:
  314.     jmp    exit            ; depart
  315.  
  316. xone2a:
  317.     cmp    member,0        ; selecting one file?
  318.     je    xonego            ; no, skip next
  319.     mov    si,offset member    ; yes, compare names
  320.     mov    di,offset archdr.mbrname
  321.     mov    cx,13
  322. xonesel:
  323.     lodsb
  324.     cmp    al,0            ; end of name
  325.     je    xonego            ; yes, select the file
  326.     cmp    al,byte ptr [di]    ; match so far?
  327.     jne    xone_agn        ; no, skip this file
  328.     inc    di
  329.     loop    xonesel
  330.     jmp    short xonego        ; it matches
  331.  
  332. ;    the following is used to skip to the next ARC entry
  333.  
  334. xone_agn:
  335.     mov    cx,word ptr archdr.mbrsize+2
  336.     mov    dx,word ptr archdr.mbrsize
  337.     add    dx,incurl        ; add current hdr offset
  338.     adc    cx,0
  339.     add    cx,incurh
  340.     mov    ax,4200h        ; skip over file data
  341.     mov    bx,archdl
  342.     int    21h
  343.     mov    incurh,dx        ; new position
  344.     mov    incurl,ax
  345.     mov    inlen,0         ; reset read buffer
  346.     jmp    xonenext
  347.  
  348. xonego:
  349.     mov    di,offset vname     ; copy file name
  350.     mov    si,offset archdr.mbrname
  351.     mov    cx,13
  352. xone3:
  353.     lodsb
  354.     cmp    al,0            ; end of name?
  355.     je    xone4
  356.     stosb
  357.     loop    xone3
  358.     jmp    short xone5
  359. xone4:
  360.     mov    al,0            ; pad with asciiz
  361.     rep    stosb
  362.  
  363. xone5:
  364.     sub    bx,bx            ; determine style
  365.     mov    bl,archdr.mbrcode
  366.     shl    bx,1
  367.     mov    wtg,bx            ; save where-to-go offset
  368.     shl    bx,1
  369.     shl    bx,1            ; times 8 for style table
  370.     lea    si,styles-8[bx]     ; get ptr to style name
  371.     mov    di,offset vstyle
  372.     mov    cx,8
  373.     rep    movsb
  374.  
  375.     print    vline            ; display this file info
  376.     cmp    outname,0        ; specified different output?
  377.     je    xone6
  378.     print    outmsg
  379.  
  380. xone6:
  381.     call    create            ; allocate new file
  382.  
  383.     mov    bx,wtg            ; where to go
  384.     jmp    where-2[bx]        ; let 'er rip
  385.  
  386.     subttl    - Extract current member file
  387.     page
  388. ;
  389. ;    1 - straight copy of all formats
  390.  
  391. copy2:
  392. unpack3:
  393. unsqueez4:
  394. uncrunch5:
  395. uncrunch6:
  396. uncrunch7:
  397. uncrunch8:
  398.  
  399. copy1:
  400.     mov    si,offset newhdr    ; copy arc header first
  401.     mov    cx,hdrlen
  402. copyhdr:
  403.     lodsb
  404.     call    putc
  405.     loop    copyhdr
  406.  
  407.     mov    cx,word ptr archdr.mbrsize
  408.     mov    dx,word ptr archdr.mbrsize+2
  409. xone7:
  410.     call    getc            ; straight copy
  411.     jc    xoner1
  412.     call    putc
  413.     sub    cx,1
  414.     sbb    dx,0
  415.     or    cx,cx            ; any more bytes?
  416.     jnz    xone7            ; yup, keep on truckin'
  417.     or    dx,dx
  418.     jnz    xone7
  419.     jmp    xonemore
  420.  
  421. xoner1: printl    'Premature EOF reading '
  422.     print    vname
  423.     jmp    error
  424.  
  425. xonemore:
  426.     mov    al,arcmark        ; append normal arc mark
  427.     call    putc
  428.     mov    al,0
  429.     call    putc
  430.  
  431.     call    putblk            ; flush buffer
  432.     call    closout         ; close output
  433.     jmp    xonenext
  434.  
  435.     subttl    ' - miscellaneous subroutines'
  436.     page
  437.  
  438. openarc proc    near            ; open new archive
  439.     push    bx
  440.     mov    dx,offset arcname
  441.     mov    ax,3d02h        ; for input and output
  442.     int    21h
  443.     jc    openerr
  444.     mov    archdl,ax        ; save file handle
  445.     clc
  446.     printl    '  Using: '
  447.     print    arcname
  448.     printl    ' '
  449.     pop    bx
  450.     ret
  451. openerr:
  452.     printl    'Unable to open archive: '
  453.     print    arcname
  454.     jmp    error
  455. openarc endp
  456.  
  457.  
  458. closarc proc    near
  459.     push    bx
  460.     mov    bx,archdl        ; previous handle
  461.     or    bx,bx            ; already open?
  462.     jz    closed
  463.     mov    ah,3eh            ; yes, so close it
  464.     int    21h
  465. closed: mov    archdl,0
  466.     pop    bx
  467.     ret
  468. closarc endp
  469.  
  470. note    proc    near            ; note location of header
  471.     push    bx            ; in ARC file
  472.     sub    cx,cx
  473.     sub    dx,dx
  474.     mov    ax,4201h        ; get file pointer to EOF
  475.     mov    bx,archdl
  476.     int    21h
  477.     mov    incurh,dx        ; save hdr position
  478.     mov    incurl,ax
  479.     pop    bx
  480.     ret
  481. note    endp
  482.  
  483. create    proc    near            ; allocate new file
  484.     push    bx
  485.     mov    found,255        ; indicate member extracted
  486.     test    reuse,1         ; want to over-write?
  487.     jnz    create1         ; yup, life in the danger zone
  488.     mov    dx,offset outname    ; output specified?
  489.     cmp    byte ptr outname,0
  490.     jne    open_it
  491.     mov    dx,offset vname     ; no, use archive member file name
  492.  
  493. open_it:
  494.     mov    ax,3d00h        ; see if file already exists
  495.     int    21h
  496.     jc    create1         ; looks good so far
  497.  
  498.     mov    bx,ax            ; close found file
  499.     mov    ah,3eh
  500.     int    21h
  501.  
  502.     print    prompt            ; ask to re-use
  503.     mov    ah,0            ; get response
  504.     int    16h
  505.     mov    answer,al        ; echo response
  506.     mov    dx,offset answer
  507.     call    prints
  508.  
  509.     cmp    answer,'Y'              ; get the okay?
  510.     je    create1
  511.     cmp    answer,'y'
  512.     je    create1
  513.     jmp    xone_agn
  514.  
  515. create1:
  516.     mov    dx,offset outname    ; output specified?
  517.     cmp    byte ptr outname,0
  518.     jne    create_it
  519.     mov    dx,offset vname     ; actual file name
  520. create_it:
  521.     sub    cx,cx            ; normal attribute
  522.     mov    ah,3ch
  523.     int    21h
  524.     jc    creater         ; something failed
  525.     mov    outhdl,ax
  526.     pop    bx
  527.     ret
  528. creater:
  529.     printl    'CREATE failed - '
  530.     print    vname
  531.     jmp    error
  532. create    endp
  533.  
  534.  
  535. closout proc    near            ; close output file
  536.     mov    bx,outhdl        ; close output
  537.     or    bx,bx            ; was it open?
  538.     jz    closedout        ; no, that's funny
  539.     mov    ah,3eh
  540.     int    21h
  541. closedout:
  542.     ret
  543. closout endp
  544.  
  545. ;
  546. ;    print string like int 21h function 9
  547.  
  548. prints    proc    near            ; dx has offset to string
  549.     push    si            ;  ending in char x'ff'
  550.     push    bx
  551.     push    cx
  552.     mov    si,dx            ; pointer to text
  553.     sub    cx,cx            ; length of text
  554. ps1:    lodsb
  555.     cmp    al,stopper        ; ending stopper code?
  556.     je    ps9
  557.     inc    cx            ; no, increment length
  558.     jmp    short ps1
  559.  
  560. ps9:    mov    ah,40h            ; write to stdout
  561.     mov    bx,1
  562.     int    21h
  563.  
  564.     pop    cx            ; recover registers
  565.     pop    bx
  566.     pop    si
  567.     ret
  568. prints    endp
  569.  
  570.     subttl    ' - i/o subroutines'
  571.     page
  572.  
  573. getc    proc    near            ; return next byte in al
  574.     push    si            ;  or cf=1 for eof
  575. getc1:
  576.     sub    inlen,1         ; any left in buffer
  577.     jns    getc2            ; yes, pick it up
  578.     call    getblk
  579.     jnc    getc1
  580.     pop    si            ; return cf=1 at eof
  581.     ret
  582. getc2:
  583.     mov    si,inptr        ; offset to next byte
  584.     lodsb
  585.     mov    inptr,si
  586.     add    incurl,1        ; bump file offset
  587.     adc    incurh,0
  588.     pop    si
  589.     ret
  590. getc    endp
  591.  
  592. getblk    proc    near            ; read next block
  593.     push    ax
  594.     push    bx
  595.     push    cx
  596.     push    dx
  597.     mov    ah,3fh            ; read from handle
  598.     mov    bx,archdl        ; arc file handle
  599.     mov    cx,inbufsz        ; input buffer size
  600.     mov    dx,offset inbuf     ; offset to input buffer
  601.     mov    inptr,dx
  602.     int    21h
  603.     jc    getblkr         ; oops
  604.     or    ax,ax            ; anything read?
  605.     jnz    getblka
  606.     stc                ; no, set cf=1 for eof
  607.     jmp    short getblkx        ; and exit
  608. getblka:
  609.     mov    inlen,ax        ; return count of bytes read
  610.     clc
  611. getblkx:
  612.     pop    dx
  613.     pop    cx
  614.     pop    bx
  615.     pop    ax
  616.     ret
  617.  
  618. getblkr:
  619.     printl    "I/O error reading from "
  620.     print    arcname
  621.     jmp    error            ; gotta quit
  622. getblk    endp
  623.  
  624.     page
  625.  
  626. putc    proc    near
  627.     cmp    outlen,0        ; any room left?
  628.     jg    putc1            ; yes, stuff into buffer
  629.     call    putblk            ; no, write out buffer
  630.     jnc    putc
  631.     ret                ; return cf=1 for error
  632.  
  633. putc1:    mov    di,outptr        ; offset to next spot
  634.     stosb
  635.     mov    outptr,di        ; update ptr for next time
  636.     dec    outlen
  637.     clc                ; return cf=0 for okay
  638.     ret
  639.  
  640. putblk: push    ax            ; save regs
  641.     push    bx
  642.     push    cx
  643.     push    dx
  644.     mov    bx,outhdl        ; output file handle
  645.     mov    cx,outsize        ; buffer size
  646.     mov    ax,cx
  647.     sub    cx,outlen        ; less bytes unfilled
  648.     mov    outlen,ax        ; reset buffer size free
  649.     mov    dx,offset outbuf    ; offset to buffer
  650.     mov    outptr,dx
  651.     jcxz    putblk0            ; have nothing to write?
  652.     mov    ah,40h            ; write to a file
  653.     int    21h
  654.     jc    putcerr         ; write failed?
  655.     cmp    ax,cx            ; wrote it all?
  656.     jne    putcerr
  657. putblk0:
  658.     clc                ; clear CF error inidcator
  659.     pop    dx            ; recover regs
  660.     pop    cx
  661.     pop    bx
  662.     pop    ax
  663.     ret
  664.  
  665. putcerr:
  666.     printl    'I/O error writing to '
  667.     print    vname
  668.     jmp    error
  669. putc    endp
  670.  
  671.     subttl    '--- load next archive header'
  672.     page
  673.  
  674. gethdr    proc    near
  675.     mov    cx,128            ; gotta look for the damn thing
  676. gethdr2:
  677.     call    getc            ; get next file byte
  678.     jc    gethdrr1        ; premature eof
  679.     cmp    al,arcmark        ; start of header?
  680.     je    gethdr3         ; yup, let's start cookin
  681.     loop    gethdr2
  682. gethdrr1:
  683.     printl    "Invalid archive format!"
  684.     jmp    error
  685.  
  686. gethdr3:
  687.     call    getc            ; get version code
  688.     jc    gethdrr1
  689.     mov    archdr.mbrcode,al
  690.     cmp    al,xoneer        ; reasonable code?
  691.     ja    gethdrr1        ; nope, funny stuff
  692.     cmp    al,0            ; archive eof?
  693.     je    gethdr9         ; yup done
  694.  
  695.     mov    cx,13            ; get member name
  696.     mov    di,offset archdr.mbrname
  697. gethdr4:
  698.     call    getc
  699.     jc    gethdrr1
  700.     stosb
  701.     loop    gethdr4
  702. gethdr5:
  703.     mov    cx,10            ; length remaining
  704.     cmp    archdr.mbrcode,1    ; old format?
  705.     je    gethdr6         ; yes, it's short
  706.     mov    cl,14
  707. gethdr6:
  708.     mov    di,offset archdr.mbrsize
  709. gethdr7:
  710.     call    getc
  711.     jc    gethdrr1
  712.     stosb
  713.     loop    gethdr7
  714. gethdr8:
  715.     cmp    archdr.mbrcode,1    ; old format?
  716.     jne    gethdr9         ; if so, it's short
  717.     mov    si,offset mbrsize
  718.     mov    di,offset mbrlen
  719.     mov    cx,4
  720.     rep    movsb
  721. gethdr9:
  722.     clc
  723.     ret
  724.  
  725. gethdrr2:
  726.     printl    'Invalid archive header'
  727.     jmp    error
  728. gethdr    endp
  729.  
  730.     subttl    '--- i/o data areas'
  731.     page
  732.  
  733. xone    endp
  734.  
  735. newhdr    db    arcmark         ; starts an arc header
  736. archdr    equ    $            ; i/o area for a header
  737. hdrlen    equ    size header + 1     ; length of normal ARC header
  738.  
  739. inbuf    equ    $ + 64            ; input buffer
  740.  
  741. outbuf    equ    inbuf + inbufsz     ; output buffer
  742.  
  743. lastbyt equ    outbuf + outbufsz
  744.  
  745. pgmsize equ    (lastbyt - xone + 1024) /16    ; paragraphs in program
  746.  
  747. cseg    ends
  748.     end    xone
  749.